/**
 * @author 蔡明宗
 * @date 2011-5-28 下午08:14:42
 */

package com.gossip.model;

public class TipDiv {

	private int width = 0;// 宽度

	private int height = 0;// 高度

	private int lineHeight = 17;

	private int length = 0;// 字符占宽度，中文占2（包括标点符号），非中文占1

	private int line = 1;// 行数

	private int maxLineLength = 0;// 最长行的长度，度量同length

	private static final int MAX_LENGTH = 18;// 标准的最长行的长度

	private String creatorWord = "";

	public String getTipStyle(Tip tip) {
		StringBuffer style = new StringBuffer(Css4TipDiv.DEFAULT_DIV_BASIC_CSS);
		// tip.addStyle(Css4TipDiv.getRamdonTop());
		// tip.addStyle(Css4TipDiv.getRamdonLeft());

		this.creatorWord = "  " + tip.getCreator();
		style.append(getDivSize(tip.getContent()));
		style.append(Css4TipDiv.getStyle(tip.getBackground()));
		return style.toString();
	}

	/**
	 * 计算最长的行和总行数
	 * 
	 * @param content
	 */
	private void computeRec(String content) {
		// 第一次计算，得出文章里最长行的长度，并算出行数
		getLineByMaxLineLength(content);
		// 如果最长行的长度大于标准长度，则重新计算行数，因为div现在的宽度增加了，有可能减少行数
		if (maxLineLength > MAX_LENGTH) {
			line = 1;// 重新计算，重置行数为1
			// 第二次计算
			getLineByMaxLineLength(content);
		}

	}

	/**
	 * 根据给定的最长行，算出行数
	 * 
	 * @param content
	 */
	private void getLineByMaxLineLength(String content) {
		int lineLength = 0;// 行的长度
		int lastIndex = 0;// 上一个可转行的字符下标
		int lastLength = 0;// 上一个可转行的长度
		char c = ' ';
		char lastC = ' ';

		// 最长行的长度
		int maxLength = Math.max(MAX_LENGTH, maxLineLength);

		for (int i = 0; i < content.length(); i++) {
			lastC = c;
			c = content.charAt(i);
			// 计算行的长度，中文占2（包括标点符号），非中文占1
			if (Common.isChiese(c)) {
				lineLength += 2;
			} else {
				lineLength += 1;
			}

			if (i > 0 && i < content.length()) {
				// 如果这两个字符之间能转行,或者已经是末尾
				if (isReturn(lastC, c) || i == content.length() - 1) {
					// 记录当前下标，记录当前的行数
					lastIndex = i;
					lastLength = lineLength;
				}
			}

			// 如果lastIndex为0，也就是从来没有断过句，那么直接下一次循环
			if (lastIndex == 0) {
				continue;
			}

			// 如果现在行长度已经超过最大的长度，那么开始断句
			if (lineLength >= maxLength) {
				// 将上一次断句时的行长度赋给当前行，相当于断句了；当前行缩短
				lineLength = lastLength;
				// 计算有没有产生更长的行。
				maxLineLength = maxLineLength > lineLength ? maxLineLength
						: lineLength;
				// 如果已经是末尾，就不必开新的一行
				if (i != content.length() - 1)
					line++;
				// System.out
				// .println(lastIndex + " :" + content.charAt(lastIndex));
				// 下标退回到断句时的下标
				i = lastIndex;
				// 重置
				lastIndex = 0;
				lineLength = 0;
				lastLength = 0;
			}
		}
	}

	/**
	 * 确定div的width和height样式
	 * 
	 * @param content
	 * @return
	 */
	private String getDivSize(String content) {
		this.resetLength();
		this.length = this.getContentlength(content);
		int creatorWordLength = this.creatorWord.length();

		// 如果长度大于于标准长度，那么开始断句；否则不必断句
		if (length > MAX_LENGTH) {
			computeRec(content);
		} else {
			maxLineLength = length;
		}
		// 如果行最大长度不等于标准最大长度
		if (maxLineLength != MAX_LENGTH) {
			// 比较当前最大长度和creatorWordLength，取其中大的值
			maxLineLength = Math.max(creatorWordLength, maxLineLength);
			width = (int) (140 * maxLineLength / lineHeight + 10);
		} else {
			width = 145;
		}

		// 多出的两行是底部和顶部信息
		height = lineHeight * (line + 2);
		return "height:" + height + "px;width:" + width + "px;";
	}

	// 连续两个中文
	// 中文加空格
	// 空格加中文
	// 英文加空格
	private boolean isReturn(char c1, char c2) {
		return Common.isChieseCharacter(c1) && Common.isChieseCharacter(c2)
				|| c1 == ' ' && Common.isChieseCharacter(c2)
				|| Common.isChieseCharacter(c1) && c2 == ' '
				|| Common.isLetter(c2) && c1 == ' ';
	}

	/**
	 * 计算文本长度
	 * 
	 * @param content
	 * @return
	 */
	private int getContentlength(String content) {
		int length = 0;
		for (int i = 0; i < content.length(); i++) {
			char c = content.charAt(i);
			if (Common.isChiese(c)) {
				length += 2;
			} else {
				length += 1;
			}

		}
		return length;
	}

	private void resetLength() {
		this.length = 0;
		line = 1;
		maxLineLength = 0;
	}
}
